package com.andy.blog.admin.service.impl;

import com.andy.blog.admin.service.ConfigBusService;
import com.andy.blog.admin.service.SysRegisterBusService;
import com.andy.blog.common.constant.BaseConstants;
import com.andy.blog.common.constant.CacheConstants;
import com.andy.blog.common.constant.ConfigCenterConstants;
import com.andy.blog.common.constant.UserConstants;
import com.andy.blog.common.core.redis.RedisCache;
import com.andy.blog.common.enums.ClientTypeEnum;
import com.andy.blog.common.exception.BlogServiceException;
import com.andy.blog.common.reponse.BlogResultCode;
import com.andy.blog.common.utils.MessageUtils;
import com.andy.blog.common.utils.SecurityUtils;
import com.andy.blog.dal.service.SysUserDalService;
import com.andy.blog.dal.vo.RegisterVO;
import com.andy.blog.dal.vo.SysLoginLogVO;
import com.andy.blog.dal.vo.SysUserVO;
import com.andy.blog.framework.manager.AsyncManager;
import com.andy.blog.framework.manager.factory.AsyncFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Created by andy on 2023/4/15 20:43
 */
@Service("sysRegisterBusService")
public class SysRegisterBusServiceImpl implements SysRegisterBusService {

    @Resource
    private SysUserDalService userService;

    @Resource
    private ConfigBusService configBusService;

    @Resource
    private RedisCache redisCache;


    @Override
    public void register(RegisterVO registerVO) {

        if (!"true".equals(configBusService.selectConfigByKey(ConfigCenterConstants.REGISTER_USER_SWITCH))) {
            throw new BlogServiceException("当前系统没有开启注册功能!");
        }

        String username = registerVO.getUsername();
        String password = registerVO.getPassword();
        SysUserVO sysUser = new SysUserVO();
        sysUser.setUserName(username);

        // 验证码开关
        boolean captchaEnabled = configBusService.selectCaptchaEnabled();
        if (captchaEnabled) {
            String redisKey = ClientTypeEnum.MANAGE.getCode().equals(registerVO.getClientType()) ?
                    CacheConstants.CAPTCHA_CODE_KEY : CacheConstants.PORTAL_CAPTCHA_CODE_KEY;
            validateCaptcha(redisKey, registerVO.getCode(), registerVO.getUuid());
        }

        if (StringUtils.isBlank(username)) {
            throw new BlogServiceException("用户名不能为空");
        } else if (StringUtils.isBlank(password)) {
            throw new BlogServiceException("用户密码不能为空");
        } else if (username.length() < UserConstants.USERNAME_MIN_LENGTH || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
            throw new BlogServiceException("账户长度必须在2到20个字符之间");
        } else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
            throw new BlogServiceException("密码长度必须在5到20个字符之间");
        } else if (!userService.checkUserNameUnique(sysUser.getId(), sysUser.getUserName())) {
            throw new BlogServiceException("保存用户[" + username + "]失败，注册账号已存在");
        }

        sysUser.setNickName(username);
        sysUser.setPassword(SecurityUtils.encryptPassword(password));

        boolean regFlag = userService.registerUser(sysUser);
        if (!regFlag) {
            throw new BlogServiceException("注册失败,请联系系统管理人员");
        }
        AsyncManager.me().execute(AsyncFactory.recordLoginLog(
                SysLoginLogVO.builder().userName(username)
                        .status(BaseConstants.REGISTER)
                        .msg(MessageUtils.message("user.register.success")).build()));
    }

    /**
     * 校验验证码
     *
     * @param code 验证码
     * @param uuid 唯一标识
     */
    public void validateCaptcha(String redisKey, String code, String uuid) {
        String verifyKey = redisKey + uuid;
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            throw new BlogServiceException(BlogResultCode.BLOG_000003);
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new BlogServiceException(BlogResultCode.BLOG_000004);
        }
    }
}
